package name.jautzy.esi.client;

import name.jautzy.esi.client.model.*;

import com.extjs.gxt.ui.client.Style.HorizontalAlignment;
import com.extjs.gxt.ui.client.Style.LayoutRegion;
import com.extjs.gxt.ui.client.data.BaseListLoader;
import com.extjs.gxt.ui.client.data.BasePagingLoadConfig;
import com.extjs.gxt.ui.client.data.BasePagingLoader;
import com.extjs.gxt.ui.client.data.ListLoadResult;
import com.extjs.gxt.ui.client.data.ListLoader;
import com.extjs.gxt.ui.client.data.PagingLoadConfig;
import com.extjs.gxt.ui.client.data.PagingLoadResult;
import com.extjs.gxt.ui.client.data.PagingLoader;
import com.extjs.gxt.ui.client.data.RpcProxy;
import com.google.gwt.user.client.rpc.AsyncCallback; 
import com.extjs.gxt.ui.client.event.ButtonEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.GridEvent;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.SelectionListener;
import com.extjs.gxt.ui.client.store.ListStore;
import com.extjs.gxt.ui.client.util.Margins;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.LayoutContainer;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.extjs.gxt.ui.client.widget.button.ToggleButton;
import com.extjs.gxt.ui.client.widget.form.CheckBox;
import com.extjs.gxt.ui.client.widget.form.ComboBox;
import com.extjs.gxt.ui.client.widget.form.FormPanel;
import com.extjs.gxt.ui.client.widget.form.NumberField;
import com.extjs.gxt.ui.client.widget.form.ComboBox.TriggerAction;
import com.extjs.gxt.ui.client.widget.form.FormPanel.LabelAlign;
import com.extjs.gxt.ui.client.widget.layout.BorderLayout;
import com.extjs.gxt.ui.client.widget.layout.BorderLayoutData;
import com.extjs.gxt.ui.client.widget.layout.ColumnData;
import com.extjs.gxt.ui.client.widget.layout.ColumnLayout;
import com.extjs.gxt.ui.client.widget.layout.FitLayout;
import com.extjs.gxt.ui.client.widget.layout.FormData;
import com.extjs.gxt.ui.client.widget.layout.FormLayout;
import com.extjs.gxt.ui.client.widget.toolbar.PagingToolBar;
import com.extjs.gxt.ui.client.widget.grid.CellEditor;
import com.extjs.gxt.ui.client.widget.grid.CheckBoxSelectionModel;
import com.extjs.gxt.ui.client.widget.grid.CheckColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnConfig;
import com.extjs.gxt.ui.client.widget.grid.ColumnModel; 
import com.extjs.gxt.ui.client.widget.grid.Grid;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class DisplayFitGridListener implements Listener<ButtonEvent> {
	private ContentPanel parent;
	private ContentPanel mypanel;
	private EsiShipFilter filter;
	private ListStore<EsiShip> sStore;
	private CheckBoxSelectionModel<EsiShip> sm;
	private Grid<EsiShip> grid;
	private PagingToolBar toolBar;
	boolean myFits = false;
		
		public DisplayFitGridListener (ContentPanel parent, boolean myFits) {
			this.parent = parent;
			this.myFits = myFits;
			resetFilter();
		}
		
		private void resetFilter() {
			filter = new EsiShipFilter();
			if (myFits) 
				filter.setUser(Esi.getEsi().getLoginInfo().getEmailAddress());			
			filter.setLimit(10);
		}
		
		public void handleEvent(ButtonEvent ce) {  
	        if (!ce.<ToggleButton> getComponent().isPressed()) {  
	          return;  
	        }  
	        
	        mypanel = new ContentPanel();
	        mypanel.setHeading("Eve Fit Database");
	        mypanel.setHeaderVisible(false);
	        mypanel.setBodyStyle("background-color:black;"
					  +"background-image:url(ressources/images/background/01_1024.jpg);"
					  +"backgroung-repeat:no-repeat;"
					  +"color:white");
	        mypanel.setLayout(new BorderLayout());
	                
		    BorderLayoutData centerData = new BorderLayoutData(LayoutRegion.CENTER);  
		    centerData.setMargins(new Margins(5));  
		    mypanel.add(createGridPanel(), centerData);		    
		    
		    BorderLayoutData southData = new BorderLayoutData(LayoutRegion.SOUTH, 100);  
		    southData.setMargins(new Margins(5));  
		    southData.setSplit(false); 
		    southData.setCollapsible(true); 
		    mypanel.add(createFilterPanel(), southData);
		    
		    mypanel.setButtonAlign(HorizontalAlignment.CENTER);
		    mypanel.setBodyBorder(false);
		    mypanel.setBorders(false);
	        
	        parent.removeAll();  
		    parent.add(mypanel);  
		    parent.layout();
		}
		
		private ContentPanel createGridPanel() {
			ContentPanel panel = new ContentPanel();  
		    panel.setHeaderVisible(false);  
		    panel.setLayout(new FitLayout());  
		    
		    RpcProxy<PagingLoadResult<EsiShip>> sProxy = new RpcProxy<PagingLoadResult<EsiShip>> () {
		    	@Override
		    	public void load(Object loadConfig, AsyncCallback<PagingLoadResult<EsiShip>> callback) {
		    		if (loadConfig != null) {
		    			PagingLoadConfig config = (PagingLoadConfig) loadConfig;
		    			filter.setOffset(config.getOffset());
		    		}
		    
		    		Esi.getEsi().getFitService().getShips(filter, callback);
		    
		    	}
		    };
		    final PagingLoader<PagingLoadResult<EsiShip>> sLoader = new BasePagingLoader<PagingLoadResult<EsiShip>>(  
		            sProxy);  
		    //sLoader.setRemoteSort(true);
		    
		    sStore = new ListStore<EsiShip>(sLoader);
		    
		    
		    toolBar = new PagingToolBar(filter.getLimit());  
		    toolBar.bind(sLoader);    
		    
		    List<ColumnConfig> columns = new ArrayList<ColumnConfig>();
		    
		    sm = new CheckBoxSelectionModel<EsiShip>();
		    columns.add(sm.getColumn());
		    
		    columns.add(new ColumnConfig("groupName", "Group", 100)); 
		    columns.add(new ColumnConfig("shipTypeName", "Type", 100)); 
		    columns.add(new ColumnConfig("shipName", "Name", 100));  
		    columns.add(new ColumnConfig("notation", "Score", 100)); 
		    ColumnConfig effColumn = new ColumnConfig("effHp", "effective HP", 100);
		    effColumn.setNumberFormat(DisplayEftFittingListener.format0D);
		    columns.add(effColumn);  
		    ColumnConfig dpsColumn = new ColumnConfig("dps", "Max Dps", 100);
		    dpsColumn.setNumberFormat(DisplayEftFittingListener.format0D);
		    columns.add(dpsColumn); 
		    
		    CheckColumnConfig checkColumn = new CheckColumnConfig("pve", "Pve?", 35);  
		    CellEditor checkBoxEditor = new CellEditor(new CheckBox());  
		    checkColumn.setEditor(checkBoxEditor);  
		    columns.add(checkColumn);
		    
		    checkColumn = new CheckColumnConfig("pvp", "Pvp?", 35);   
		    checkColumn.setEditor(checkBoxEditor);  
		    columns.add(checkColumn);
		    
		    ColumnModel cm = new ColumnModel(columns);
		    
		    grid = new Grid<EsiShip>(sStore,cm);
		    grid.setSelectionModel(sm);
		    grid.addPlugin(sm);
		    grid.addListener(Events.Attach, new Listener<GridEvent<EsiShip>>() {  
		        public void handleEvent(GridEvent<EsiShip> be) {  
		          PagingLoadConfig config = new BasePagingLoadConfig();  
		          config.setOffset(0);  
		          config.setLimit(filter.getLimit());  
		            
		          Map<String, Object> state = grid.getState();  
		          if (state.containsKey("offset")) {  
		            int offset = (Integer)state.get("offset");  
		            int limit = (Integer)state.get("limit");  
		            config.setOffset(offset);  
		            config.setLimit(limit);  
		          }  
		           
		          sLoader.load(config);  
		        }  
		      });  
		      grid.setLoadMask(true);  
		    panel.add(grid);
		    
		    panel.setBottomComponent(toolBar);  
		    
			return panel;
		}
		
		private FormPanel createFilterPanel() {
			FormPanel south = new FormPanel();
		    FormData formData = new FormData("100%");
		    south.setHeading("Filters");
		    south.setButtonAlign(HorizontalAlignment.CENTER);
		    LayoutContainer main = new LayoutContainer();
		    main.setLayout(new ColumnLayout());
		    
		    LayoutContainer left = new LayoutContainer();
		    left.setStyleAttribute("paddingRight", "10px");
		    FormLayout leftLayout = new FormLayout();
		    leftLayout.setLabelAlign(LabelAlign.LEFT);
		    left.setLayout(leftLayout);
		    
		    
		    RpcProxy<List<EdbGroup>> gProxy = new RpcProxy<List<EdbGroup>> () {
		    	@Override
		    	public void load(Object loadconfig, AsyncCallback<List<EdbGroup>> callback) {
		    		Esi.getEsi().getDatabaseService().getShipGroups(callback);
		    	}
		    };
		    ListLoader<ListLoadResult<EdbGroup>> gLoader = new BaseListLoader<ListLoadResult<EdbGroup>>(gProxy);
		    ListStore<EdbGroup> gStore = new ListStore<EdbGroup>(gLoader); 
		    final ComboBox<EdbGroup> gBox = new ComboBox<EdbGroup>();
		    gBox.setStore(gStore);
		    gBox.setFieldLabel("Ships group");
		    gBox.setEmptyText("all groups");
		    gBox.setDisplayField("name");
		    gBox.setTriggerAction(TriggerAction.ALL);
		    left.add(gBox,formData);
		    final NumberField hpField = new NumberField();
		    hpField.setFieldLabel("Effective Hp ");
		    hpField.setAllowDecimals(false);
		    hpField.setAllowNegative(false);
		    hpField.setLabelSeparator(">");
		    //left.add(hpField,formData);    
		    
		    LayoutContainer center = new LayoutContainer();
		    center.setStyleAttribute("paddingLeft", "10px");
		    center.setStyleAttribute("paddingRight", "10px");
		    FormLayout centerLayout = new FormLayout();
		    centerLayout.setLabelAlign(LabelAlign.LEFT);
		    center.setLayout(centerLayout);
		    
		    ListStore<EdbRace> rStore = new ListStore<EdbRace>();
		    rStore.add(EdbRace.all);
		    rStore.add(EdbRace.caldari);
		    rStore.add(EdbRace.gallente);
		    rStore.add(EdbRace.minmatar);
		    rStore.add(EdbRace.amarr);
		    final ComboBox<EdbRace> rBox = new ComboBox<EdbRace>();
		    rBox.setStore(rStore);
		    rBox.setFieldLabel("Ships race");
		    rBox.setEmptyText("all races");
		    rBox.setDisplayField("name");
		    rBox.setTriggerAction(TriggerAction.ALL);
		    center.add(rBox,formData);
		    final NumberField dpsField = new NumberField();
		    dpsField.setFieldLabel("max DPS ");
		    dpsField.setLabelSeparator(">");
		    dpsField.setAllowDecimals(false);
		    dpsField.setAllowNegative(false);
		    //center.add(dpsField,formData);
		    
		    LayoutContainer right = new LayoutContainer();
		    right.setStyleAttribute("paddingLeft", "10px");
		    FormLayout rightLayout = new FormLayout();
		    rightLayout.setLabelAlign(LabelAlign.LEFT);
		    right.setLayout(rightLayout);
		    final CheckBox pvpCheck = new CheckBox();
		    pvpCheck.setFieldLabel("is a pvp fit");
		    final CheckBox pveCheck = new CheckBox();
		    pveCheck.setFieldLabel("is a pve fit");
		    //right.add(pvpCheck,formData);
		    //right.add(pveCheck,formData);
		    
		    
		    main.add(left,new ColumnData(.33));
		    main.add(center,new ColumnData(.33));
		    main.add(right,new ColumnData(.33));
		    
		    south.add(main, new FormData("100%"));
		    
		    
		    Button myButton = new Button("Copy");
		    myButton.addSelectionListener(new SelectionListener<ButtonEvent>() {  
		    	@Override  
				public void componentSelected(ButtonEvent ce) {
		    		EsiShip selected = sm.getSelectedItem();
		    		String fitId = selected.getId();
		    		AsyncCallback<Void> callback = new AsyncCallback<Void>() {
		    			
						public void onSuccess(Void result) {
							Esi.getEsi().addMessage("Fit added to MyFits ");
						}

						public void onFailure(Throwable caught) {
							Esi.getEsi().addMessage("can't add fit to MyFits : "+caught.toString());
						}
					};
					Esi.getEsi().getFitService().addFitUser(fitId, callback);
					
				}  
			}); 
		    if (!myFits)
		    	mypanel.addButton(myButton);
		    
		    if (myFits)
		    	mypanel.addButton(new Button("Import", new AddEftFittingListener(sStore)));
		    
		    Button filterButton = new Button("Filter");
		    filterButton.addSelectionListener(new SelectionListener<ButtonEvent>() {  
				@Override  
				public void componentSelected(ButtonEvent ce) {
					
					if (gBox.getValue()!=null)
						filter.setGroupName(gBox.getValue().getName());
					if (rBox.getValue()!=null)
						filter.setRace(rBox.getValue().getName());
					filter.setPve(pveCheck.getValue());
					filter.setPvp(pvpCheck.getValue());
					Number num = dpsField.getValue();
					if (num!=null)
						filter.setDps(num.doubleValue());
					num = hpField.getValue();
					if (num!=null)
						filter.setEffHp(num.doubleValue());
					
					
					toolBar.first();
				}  
			}); 
		    mypanel.addButton(filterButton);
		    
		    Button resetButton = new Button("Reset");
		    resetButton.addSelectionListener(new SelectionListener<ButtonEvent>() {  
				@Override  
				public void componentSelected(ButtonEvent ce) {
					resetFilter();
					pveCheck.setValue(false);
					pvpCheck.setValue(false);
					gBox.reset();
					rBox.reset();
				}  
			}); 
		    mypanel.addButton(resetButton);
		    
		    
		    mypanel.addButton(new Button("Display", new DisplayEftFittingListener(sm)));
		    
		    Button remove = new Button("Remove");
		    remove.addSelectionListener(new SelectionListener<ButtonEvent>() {  
				@Override  
				public void componentSelected(ButtonEvent ce) {
					
					List<EsiShip> selected = sm.getSelectedItems();
					List<String> ids = new LinkedList<String>();
					sm.deselectAll();
					for (EsiShip b : selected) {
							sStore.remove(b);
							ids.add(b.getId());
					}

					AsyncCallback<Void> callback = new AsyncCallback<Void>() {
						public void onSuccess(Void result) {
							sStore.commitChanges();  
							Esi.getEsi().addMessage("Fit Removed");
						}

						public void onFailure(Throwable caught) {
							Esi.getEsi().addMessage("Can't remove bonuses : "+caught.toString());
							sStore.rejectChanges();
						}
					};
					Esi.getEsi().getFitService().removeShips(ids, callback);


				}  
			}); 
		    if (myFits)
		    	mypanel.addButton(remove);
		    
		    Button regen = new Button("Regen");
		    regen.addSelectionListener(new SelectionListener<ButtonEvent>() {  
				@Override  
				public void componentSelected(ButtonEvent ce) {				
					List<EsiShip> selected = sm.getSelectedItems();
					sm.deselectAll();
					AsyncCallback<Void> callback = new AsyncCallback<Void>() {
						public void onSuccess(Void result) {
							Esi.getEsi().addMessage("Fit Regen successful");
						}

						public void onFailure(Throwable caught) {
							Esi.getEsi().addMessage("Can't regen fit : "+caught.toString());
						}
					};
					
					for (EsiShip b : selected) {
							Esi.getEsi().getFitService().regenShip(b.getId(), callback);
					}
				}  
			}); 
		    if (myFits)
		    	mypanel.addButton(regen);
		    return south;
		}
		

}
